package com.pony.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.LambdaUpdateWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.pony.dto.PageDTO;
import com.pony.dto.TypeDTO;
import com.pony.entity.Goods;
import com.pony.entity.Type;
import com.pony.enums.AppHttpCodeEnum;
import com.pony.mapper.GoodsMapper;
import com.pony.mapper.TypeMapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pony.result.R;
import com.pony.service.IGoodsService;
import com.pony.service.ITypeService;
import com.pony.utils.BeanUtils;
import com.pony.utils.CollUtils;
import com.pony.utils.StringUtils;
import com.pony.utils.TXCloudFileUtils;
import com.pony.vo.PageVO;
import com.pony.vo.TypeAndGoodsVO;
import com.pony.vo.TypePageVO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author pony
 * @since 2023-11-16
 */
@Service
public class TypeServiceImpl extends ServiceImpl<TypeMapper, Type> implements ITypeService {
    @Autowired
    private GoodsMapper goodsMapper;

    /**
     * 添加类别
     * @param typeDTO
     * @return
     */
    @Override
    public R addType(TypeDTO typeDTO) {
        // 1、属性拷贝
        Type type = BeanUtils.copyBean(typeDTO, Type.class);
        // 2、添加前判断分类名称是否有重复
        List<Type> listDB = lambdaQuery()
                .eq(Type::getName, type.getName())
                .list();
        if (CollUtils.isNotEmpty(listDB)&&listDB.size()>=1){
            return R.error(AppHttpCodeEnum.DATA_REPEAT);
        }
        // 3、添加分类
        save(type);
        return R.success().message("分类添加成功");
    }

    /**
     * 获取分类分页信息
     * @param pageDTO
     * @return
     */
    @Override
    public R getPage(PageDTO pageDTO) {
        Page<Type> page = new Page<>(pageDTO.getCurrent(), pageDTO.getSize());
        Page<Type> typePage = lambdaQuery()
                .like(!StringUtils.isBlank(pageDTO.getKeyword()), Type::getName, pageDTO.getKeyword())
                .page(page);
        return R.success().message("分类分页信息").data("singerPage", typePage);
    }

    /**
     * 更改分类状态
     * @param id
     * @param status
     * @return
     */
    @Override
    public void setStatus(Integer id, Integer status) {
        lambdaUpdate()
                .eq(Type::getId, id)
                .set(Type::getStatus, status)
                .update();
    }

    /**
     * 根据分类id，查询单个歌手信息
     * @param id
     * @return
     */
    @Override
    public R selectOneById(Integer id) {
        Type type = getById(id);
        return R.success().message("根据id，查询单个分类数据").data("singer", type);
    }

    /**
     * 修改数据
     * @param typeDTO
     * @return
     */
    @Override
    public R updateSinger(TypeDTO typeDTO) {
        // 1、修改前判断酒水名称是否有重复
        List<Type> listDB = lambdaQuery()
                .eq(StringUtils.isNotBlank(typeDTO.getName()), Type::getName, typeDTO.getName())
                .list();
        // 自己是一定会被查出来的，自己不算，所以是 >= 2
        if (listDB.size()>=2){
            return R.error(AppHttpCodeEnum.DATA_REPEAT);
        }
        // 2、修改
        lambdaUpdate()
                .eq(Type::getId, typeDTO.getId())
                .set(Type::getName, typeDTO.getName())
                .set(Type::getRemarks, typeDTO.getRemarks())
                .update();
        return R.success().message("修改成功");
    }

    /**
     * 根据id删除分类
     * @param id
     * @return
     */
    @Override
    public R deleteOneById(Integer id) {
        // 1、删除之前要判断，分类下面没有商品了才可以删除
        List<Goods> goods = goodsMapper.selectList(new LambdaQueryWrapper<Goods>()
                .eq(Goods::getTypeId, id));
        if (CollUtils.isNotEmpty(goods)||goods.size()>0){
            return R.error().message("分类下还有商品不能删除");
        }
        // 2、删除
        removeById(id);
        return R.success().message("删除成功");
    }

    /**
     * 批量删除
     * @param ids
     * @return
     */
    @Override
    public R deleteBatch(List<Integer> ids) {
        // 1、删除之前要判断，分类下面没有商品了才可以删除
        List<Goods> goods = goodsMapper.selectListByIds(ids);
        if (CollUtils.isNotEmpty(goods)||goods.size()>0){
            return R.error().message("分类下还有商品不能删除");
        }
        // 2、删除
        removeByIds(ids);
        return R.success().message("批量删除成功");
    }

    /**
     * 查询所有分类信息
     * @return
     */
    @Override
    public R selectAll() {
        // 1、查询
        List<Type> typeList = lambdaQuery()
                // 状态必须正常
                .eq(Type::getStatus, 1)
                .list();
        return R.success().data("typeList", typeList);
    }

    /**
     * 获取分类分页信息，包含分类下的所有酒水信息
     * @param pageDTO
     * @return
     */
    @Override
    public R getPageAll(PageDTO pageDTO) {
        // 1、查询分页数据
        Page<Type> page = new Page<>(pageDTO.getCurrent(), pageDTO.getSize());
        Page<Type> typePage = lambdaQuery()
                // 状态必须正常
                .eq(Type::getStatus, 1)
                .like(!StringUtils.isBlank(pageDTO.getKeyword()), Type::getName, pageDTO.getKeyword())
                .page(page);
        // 2、封装vo
        List<Type> typeList = typePage.getRecords();
        // 属性拷贝
        List<TypeAndGoodsVO> typeAndGoodsVOS = BeanUtils.copyList(typeList, TypeAndGoodsVO.class);
        // 查询所有Goods
        List<Goods> goodsList = goodsMapper.selectList(new LambdaQueryWrapper<Goods>()
                .eq(Goods::getStatus, 1));
        // 对goodsList进行按 TypeId 分组
        Map<Long, List<Goods>> goodsMap = goodsList.stream().collect(Collectors.groupingBy(Goods::getTypeId));
        // 遍历 typeAndGoodsVOS，填充
        typeAndGoodsVOS.stream()
                .forEach(vo->vo.setRecords(goodsMap.get(vo.getId())));
        // 将分类下面没有酒品的都过滤掉，没必要展示
        List<TypeAndGoodsVO> records = typeAndGoodsVOS.stream()
                .filter(t -> CollUtils.isNotEmpty(t.getRecords()) && t.getRecords().size() > 0)
                .collect(Collectors.toList());

        PageVO<TypeAndGoodsVO> pageVO = new PageVO<>();
        pageVO.setCurrent(pageDTO.getCurrent());
        pageVO.setSize(pageDTO.getSize());
        pageVO.setTotal(typePage.getTotal());
        pageVO.setRecords(records);
        return R.success().message("分类分页信息").data("singerPage", pageVO);
    }

    @Override
    public R selectById(Integer id, PageDTO pageDTO) {
        // 1、查询数据库
        Type type = getById(id);
        // 2、封装vo数据
        TypePageVO<Goods> typePageVO = BeanUtils.copyBean(type, TypePageVO.class);

        // 查询酒水分页数据
        Page<Goods> page = new Page<>(pageDTO.getCurrent(), pageDTO.getSize());
        Page<Goods> goodsPage = goodsMapper.selectPage(page, new LambdaQueryWrapper<Goods>()
                // 状态必须正常
                .eq(Goods::getStatus, 1)
                .eq(Goods::getTypeId, id));
        PageVO<Goods> goodsPageVO = new PageVO<>();
        goodsPageVO.setRecords(goodsPage.getRecords());
        goodsPageVO.setCurrent((int) goodsPage.getCurrent());
        goodsPageVO.setSize((int) goodsPage.getSize());
        goodsPageVO.setTotal(goodsPage.getTotal());

        typePageVO.setPageInfo(goodsPageVO);

        return R.success().message("单个分类所有信息").data("singerInfo", typePageVO);
    }
}
